///********************************************************************
///* Copyright © 2011 fishr (fishr.flash@gmail.com)  
///********************************************************************


package su.fishr.effects
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.events.TimerEvent;
	import flash.filters.BlurFilter;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	
	   

	/**
	 *  Создает хвост за перемещаемым DisplayObject.
	 * Хвост создается с помощью постоянного клонирования 
	 * изображения объекта в экземпляры Bitmap из
	 * изначально созданного массива BitmapData. Это
	 * значит, что если вид перемещаемого объекта изменяется
	 * это никак не будет учитываться экземпляром класса.
	 * 
	 * 
	 * @playerversion          Flash 9
	 * @langversion            3.0
	 * @author                 fishr
	 * @created                06.12.2011 5:19
	 * @since                  06.12.2011 5:19
	 * @version				   1.0.142.0
	 */
	public  class TailDObject
	{
	/**-------------------------------------------------------------------------------
	* 
	*	   						V A R I A B L E ' S 	
	* 
	* --------------------------------------------------------------------------------
	*/
	//{
		static private const AUTHOR:String = "fishr (fishr.flash@gmail.com)";
		private var _targetDO:DisplayObject;
		private var _rateAlpha:Number;
		private var _bData:BitmapData;
		private var _arrBitmaps:Array;
		private var _timer:Timer;
		private var _alpha:Number = .7;

	//}
	
	/**-------------------------------------------------------------------------------
	* 
	*	 						P R O P E R T I E S 	
	* 
	* --------------------------------------------------------------------------------
	*/
	//{
		/**
		 * В экземпляр класса можно сообщить новый целевой 
		 * объект, при этом массив BitmapData обновится и
		 * вид "хвоста" изменится.
		 */
		public function set targetDO(value:DisplayObject):void 
		{
			_targetDO = value;
			
			init();
		}
	
	//}
	/**-------------------------------------------------------------------------------
	* 
	*								P U B L I C 	
	* 
	* --------------------------------------------------------------------------------
	*/
	//{
		/**
		 *   Конструктор принимает ссылку на
		 * объект за которым надо будет выстраивать
		 * "хвост".
		 * 
		 * @param	targetDO ссылка на DisplayObject за которым будет выстраиваться "хвост".
		 */
		public function TailDObject(targetDO:DisplayObject)
		{
			_targetDO = targetDO;
			
			init();
			
		}
		
		/**
		 * Инициализирует начало выстраивания "хвоста" за объектом.
		 * @param	timeLive  длительность "жизни" каждого эл-та "хвоста",
		 * 			с помощью этого парам. можно регулировать длинну "хвоста".
		 */
		public function createTail(timeLive:Number = .7):void
		{
			_rateAlpha = checkTimeLive( timeLive );
			
			_timer = new Timer( 10 );
			_timer.addEventListener(TimerEvent.TIMER, timeCreateTailHandler );
			_timer.start();
		}
		
		/**
		 *  Уничтожение "хвоста", и всех созданных им объектов.
		 * 
		 */
		
		public function removeTail():void
		{
			_timer.removeEventListener(TimerEvent.TIMER, timeCreateTailHandler );
			_timer.stop();
			
			var i:int = 0;
			
			do
			{
				_targetDO.parent.removeChild( _arrBitmaps[i] );
			}
			while ( i++ < _arrBitmaps.length - 1 );
			
			_arrBitmaps = null;
			_bData.dispose();
			_bData = null;
		}
		
		
		
		
	//}
	
	/**-------------------------------------------------------------------------------
	* 
	*								P R I V A T E 	
	* 
	* --------------------------------------------------------------------------------
	*/	
	//{
		private function init():void
		{
			_bData = new BitmapData( _targetDO.width, _targetDO.height, true, 0xFF );
			_bData.draw( _targetDO, null, null, null, new Rectangle( 0, 0, _targetDO.width, _targetDO.height), false);
			_arrBitmaps = new Array();
		}
		
		private function timeCreateTailHandler(e:TimerEvent):void 
		{
			if ( _arrBitmaps.length > 1)
			{
				var i:int = 0;
				var blur:BlurFilter;
			
				do
				{
					_arrBitmaps[i].alpha -= _rateAlpha;
					blur = new BlurFilter( 25/i, 25/i )
					_arrBitmaps[i].filters = [blur];
					
					if ( _arrBitmaps[i].alpha <= 0 )
					{
						if ( _arrBitmaps[i].parent )
						{
							_targetDO.parent.removeChild( _arrBitmaps[i] );
							_arrBitmaps.splice( _arrBitmaps[i], 1 );
						}
						
					}
				}
				while ( i++ < _arrBitmaps.length - 1 );
			
			
				if ( _arrBitmaps[ _arrBitmaps.length - 1 ].x === _targetDO.x &&
						_arrBitmaps[ _arrBitmaps.length - 1 ].y === _targetDO.y) return;

			}
			
			
						
			var bMap:Bitmap = new Bitmap( _bData );
			bMap.alpha = _alpha;
			var index:int = _targetDO.parent.getChildIndex( _targetDO );
			
			bMap.x = _targetDO.x;
			bMap.y = _targetDO.y;
			_arrBitmaps.push( bMap );
			_targetDO.parent.addChildAt( bMap, index === 0? 0: index - 1 );

			
		}
		
		private function checkTimeLive(timeLive:Number):Number
		{
			var frameLive:int = timeLive * _targetDO.loaderInfo.frameRate;
			var rateAlpha:Number = _alpha / frameLive;
			
			return rateAlpha;
		}
		

		

		
	//}
		
		
	}

}